package com.wyf.test.widget;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;

import com.wyf.test.R;
import com.wyf.test.util.Tools;

import java.lang.ref.WeakReference;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 转圈圈
 */
public class LoadCircleView extends View {

    private static final String TAG = "LoadCircleView";

    /**
     * 刷新加载动画的消息标识
     */
    private static final int MSG_REFRESH_ANIMATION = 0x1001;

    /**
     * 主圆画笔
     */
    private Paint mPrimaryPaint;

    /**
     * 次圆画笔
     */
    private Paint mSecondaryPaint;

    /**
     * 遮盖声波纹的画笔
     */
    private Paint mMaskPaint;

    /**
     * 动画的最终半径
     */
    private float mEndRadius;

    /**
     * 动画的当前半径
     */
    private float mCurrentRadius;

    /**
     * 主圆线条宽度，单位dp
     */
    private float mPrimaryWidth = 2.0f;

    /**
     * 次圆线条宽度，单位dp
     */
    private float mSecondaryWidth = 2.0f;

    /**
     * 两个圆最大间距，单位dp
     */
    private float mMaxInterval = 0.5f;

    /**
     * 次圆透明度百分比
     */
    private float mSecondaryAlphaRatio = 0.6f;

    /**
     * 整体透明度
     */
    private float mAlphaRatio = 0f;

    /**
     * 画笔透明度最大值
     */
    private static final int MAX_ALPHA_VALUE = 255;

    /**
     * 用于遮盖波纹的蒙板颜色
     */
    private int mMaskColor;

    /**
     * 父 view 的宽度（单位 px）
     */
    private int mWidth;

    /**
     * 父 view 的高度（单位 px）
     */
    private int mHeight;

    /**
     * 画布旋转角度
     */
    private float mDegree = 0f;

    /**
     * 半径变大属性动画持续时间
     */
    private long mSizeIncreaseTime = 250 / 7 * 5;

    /**
     * 半径变小属性动画持续时间
     */
    private long mSizeDecreaseTime = 250 / 7 * 3;

    /**
     * 透明度属性动画持续时间
     */
    private long mAlphaAnimatorTime = 250 / 7 * 8;

    /**
     * 组合动画，控制多个属性动画执行顺序
     */
    private AnimatorSet mAnimatorSet;

    /**
     * 计时器，用于控制两帧之间的时间间隔（半径不变之后）
     */
    private Timer mTimer;

    /**
     * 主线程 handler
     */
    private MainThreadHandler mMainHandler;

    /**
     * 动画开始标志
     */
    private boolean mIsBegin = false;

    public LoadCircleView(Context context, float radius, int maskColor) {
        this(context, null);
        mEndRadius = radius;
        mMaskColor = maskColor;
        initialize();
    }

    public LoadCircleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LoadCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private static class MainThreadHandler extends Handler {

        private WeakReference<LoadCircleView> mWeakLoadCircleView;

        public MainThreadHandler(LoadCircleView loadCircleView) {
            mWeakLoadCircleView = new WeakReference<LoadCircleView>(loadCircleView);
        }

        @Override
        public void handleMessage(Message msg) {
            if (msg.what == MSG_REFRESH_ANIMATION) {
                LoadCircleView loadCircleView = mWeakLoadCircleView.get();
                if (loadCircleView != null) {
                    loadCircleView.invalidate();
                }
            }
        }
    }

    /**
     * 设置蒙板颜色
     */
    public void setMaskColor(int maskColor) {
        mMaskColor = maskColor;
    }

    /**
     * 初始化
     */
    private void initialize() {

        mMainHandler = new MainThreadHandler(this);

        // 初始化主圆画笔
        mPrimaryPaint = new Paint();
        mPrimaryPaint.setAntiAlias(true);
        mPrimaryPaint.setStyle(Paint.Style.STROKE);
        mPrimaryPaint.setStrokeWidth(Tools.dip2px(getContext(), mPrimaryWidth));

        // 初始化次圆画笔
        mSecondaryPaint = new Paint();
        mSecondaryPaint.setAntiAlias(true);
        mSecondaryPaint.setStyle(Paint.Style.STROKE);
        mSecondaryPaint.setStrokeWidth(Tools.dip2px(getContext(), mSecondaryWidth));

        // 初始化主圆画笔
        if (mMaskColor != -1) {
            mMaskPaint = new Paint();
            mMaskPaint.setAntiAlias(true);
            mMaskPaint.setStyle(Paint.Style.FILL);
            mMaskPaint.setColor(mMaskColor);
        }

    }

    /**
     * 开始加载动画
     */
    public void begin() {
        if (mIsBegin == true) {
            return;
        }

        mIsBegin = true;
        // 大小改变的属性动画监听器
        ValueAnimator.AnimatorUpdateListener radiusAnimatorListener = new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mCurrentRadius = (Float) animation.getAnimatedValue();

                // 根据当前半径大小，设置画笔颜色渐变
                int primaryStartColor = getResources().getColor(R.color.duer_voice_primary_start);
                int primaryEndColor = getResources().getColor(R.color.duer_voice_primary_end);
                LinearGradient primaryPaintLG = new LinearGradient(mWidth / 2 - mCurrentRadius, 0,
                        mWidth / 2 + mCurrentRadius, 0, primaryStartColor, primaryEndColor, Shader.TileMode.MIRROR);
                mPrimaryPaint.setShader(primaryPaintLG);

                int secondaryStartColor = getResources().getColor(R.color.duer_voice_secondary_start);
                int secondaryEndColor = getResources().getColor(R.color.duer_voice_secondary_end);
                LinearGradient secondaryPaintLG = new LinearGradient(mWidth / 2 - mCurrentRadius, 0,
                        mWidth / 2 + mCurrentRadius, 0, secondaryStartColor, secondaryEndColor, Shader.TileMode.MIRROR);
                mSecondaryPaint.setShader(secondaryPaintLG);
            }
        };

        // 圆形刚出现时的半径大小
        float initRadius = mEndRadius / 3;
        // 圆形变到最大时的半径大小
        float largeRadius = mEndRadius * 23 / 21;

        // 半径变大属性动画
        ValueAnimator mSizeIncrease = ValueAnimator.ofFloat(initRadius, largeRadius);
        mSizeIncrease.setInterpolator(new LinearInterpolator());
        mSizeIncrease.setDuration(mSizeIncreaseTime);
        mSizeIncrease.addUpdateListener(radiusAnimatorListener);

        // 半径变小属性动画
        ValueAnimator mSizeDecrease = ValueAnimator.ofFloat(largeRadius, mEndRadius);
        mSizeDecrease.setInterpolator(new LinearInterpolator());
        mSizeDecrease.setDuration(mSizeDecreaseTime);
        mSizeDecrease.addUpdateListener(radiusAnimatorListener);

        // 透明度改变属性动画
        ValueAnimator mAlphaAnimator = ValueAnimator.ofFloat(0, 1);
        mAlphaAnimator.setInterpolator(new DecelerateInterpolator());
        mAlphaAnimator.setDuration(mAlphaAnimatorTime);
        mAlphaAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mAlphaRatio = (Float) animation.getAnimatedValue();
                mPrimaryPaint.setAlpha((int) (MAX_ALPHA_VALUE * mAlphaRatio));
                mSecondaryPaint.setAlpha((int) (mSecondaryAlphaRatio * MAX_ALPHA_VALUE * mAlphaRatio));
                invalidate();
            }
        });

        // 组合动画播放顺序
        mAnimatorSet = new AnimatorSet();
        mAnimatorSet.play(mAlphaAnimator).with(mSizeIncrease);
        mAnimatorSet.play(mSizeDecrease).after(mSizeIncrease);
        mAnimatorSet.start();

        mTimer = new Timer();
        // 动画播放结束后，定时刷新界面显示旋转
        mAnimatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mTimer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        mMainHandler.sendEmptyMessage(MSG_REFRESH_ANIMATION);
                    }
                }, 0, 16);
            }
        });

    }

    /**
     * 停止旋转
     */
    public void finish() {

        if (mIsBegin == false) {
            return;
        }

        mIsBegin = false;

        if (mAnimatorSet != null) {
            mAnimatorSet.cancel();
            mAnimatorSet = null;
        }

        if (mTimer != null) {
            mTimer.cancel();
            mTimer = null;
        }

        mMainHandler.removeMessages(MSG_REFRESH_ANIMATION);
        reset();

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawColor(Color.TRANSPARENT);

        if (mDegree == 0) {
            mWidth = ((ViewGroup) getParent()).getWidth();
            mHeight = ((ViewGroup) getParent()).getHeight();

            // 如果设置的最终半径相对于父容器太大，则根据父容器修改半径
            if (mEndRadius >= Math.min(mWidth, mHeight) / 2 * 0.8f) {
                mEndRadius = Math.min(mWidth, mHeight) / 2 * 0.8f;
            }
        }

        mDegree += 6.0f;
        if (mDegree >= 360.0f) {
            mDegree = 0.0f;
        }
        canvas.save();
        canvas.rotate(mDegree, mWidth / 2, mHeight / 2 + (Tools.dip2px(getContext(), mMaxInterval) - 1f));

        if (mMaskColor != -1) {
            canvas.drawCircle(mWidth / 2, mHeight / 2, mCurrentRadius + Tools.dip2px(getContext(), mPrimaryWidth),
                    mMaskPaint);
        }

        canvas.drawCircle(mWidth / 2, mHeight / 2, mCurrentRadius, mPrimaryPaint);

        canvas.restore();
        canvas.rotate(mDegree, mWidth / 2, mHeight / 2 - (Tools.dip2px(getContext(), mMaxInterval) - 1f));
        canvas.drawCircle(mWidth / 2, mHeight / 2, mCurrentRadius, mSecondaryPaint);

    }

    private void reset() {
        mCurrentRadius = 0f;
        mDegree = 0f;
        mAlphaRatio = 0f;
    }
}